package com.jddup.program.etm;

import com.baomidou.mybatisplus.annotation.TableName;
import com.jddup.common.annotations.ColumnDes;
import com.jddup.common.annotations.TableDesc;
import com.jddup.common.pojo.TableColumn;
import com.jddup.common.pojo.TableMeta;
import com.jddup.program.utils.Misc;
import com.jddup.program.utils.ReflectionUtils;

import javax.persistence.Table;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by ZZB on 2017/12/4.
 */
public class EntityToTableMetaConvertorImpl implements EntityToTableMetaConvertor {
    private FieldToTableColumnConvertor fieldToTableColumnConvertor;
    private TableColumnColumnDesConvertor tableColumnColumnDesConvertor;

    public EntityToTableMetaConvertorImpl(FieldToTableColumnConvertor fieldToTableColumnConvertor,
                                          TableColumnColumnDesConvertor tableColumnColumnDesConvertor) {
        this.fieldToTableColumnConvertor = fieldToTableColumnConvertor;
        this.tableColumnColumnDesConvertor = tableColumnColumnDesConvertor;
    }

    @Override
    public <T> TableMeta convertFromClass(Class<T> clazz) {
        TableMeta tableMeta = new TableMeta();
        tableMeta.setBeanClass(clazz);
        String tableName = null;
        try {
            if (Class.forName("javax.persistence.Table") != null) {
                Table table = null;
                table = clazz.getAnnotation(Table.class);
                tableName = table.name();
            }
        } catch (Throwable e) {
            //
        }

        try {
            if (Class.forName("com.baomidou.mybatisplus.annotation.TableName") != null) {
                TableName anTableName = clazz.getAnnotation(TableName.class);
                tableName = anTableName.value();
            }
        } catch (Throwable e) {
            //
        }

        try {
            TableDesc tableDesc = clazz.getAnnotation(TableDesc.class);
            tableMeta.setTableComment(tableDesc.comment());
        } catch (Throwable e) {
            //
        }

        if (tableName == null) {
            tableName = Misc.camelToUnderline(clazz.getSimpleName());
        }

        tableMeta.setTableName(tableName);
        tableMeta.setBeanName(clazz.getSimpleName());
        Field[] fields = ReflectionUtils.getAllDeclaredFields(clazz);
        {
            // tableColumns
            List<TableColumn> tableColumns = new ArrayList<>();
            for (Field declaredField : fields) {
                TableColumn tableColumn = fieldToTableColumnConvertor.convertFromField(declaredField);
                ColumnDes columnDes = declaredField.getAnnotation(ColumnDes.class);
                if (columnDes != null) {
                    tableColumnColumnDesConvertor.convertFromColumnDes(tableName, tableColumn, columnDes);
                }
                fieldToTableColumnConvertor.buildFullType(tableColumn);
                tableColumns.add(tableColumn);
                if (tableColumn.getPrimaryKey()) {
                    tableMeta.setPrimaryKeyColumn(tableColumn);
                }
            }
            tableMeta.setTableColumns(tableColumns);
        }
        return tableMeta;
    }
}
